package week14;

/*
    简单 的双向链表数据结构
 */
public class LinkedList01 {
    public static void main(String[] args) {
        // 模拟一个简单的双向链表结构

       Node liuB = new Node("刘备");
       Node guanY =  new Node("关羽");
       Node zhangF = new Node("张飞");

       // 现在 在堆里面这 三个对象还是孤零零的 没有联系

        // 链接三个节点，形成 双向链表
        // 刘备 -> 关羽 -> 张飞
        liuB.next = guanY; // 思考下内存里干了啥 -- 画内存图
        guanY.next = zhangF;

        // 反向建立联系  到这里才是真正的双向链表
        // 张飞 -> 关羽 -> 刘备
        zhangF.pre = guanY;
        guanY.pre = liuB;

        Node first = liuB; // 让 first 引用指向 jack, 就是双向链表的头节点
        Node last = zhangF; //  让 last 引用指向 lx, 就是双向链表的尾节点

        // 那这个数据结构的特点 对比 ArrayList （数组） 的特点是什么呢？

        // 演示从头到尾遍历
        System.out.println("=========");
        while (true) { // 画桌面截图
            if (first == null) {
                break;
            }
            // 输出 first 信息
            System.out.println(first);
            first = first.next; // 指针向后移动一位 -- 画桌面截图
        }

        // 演示，从尾到头的遍历
        System.out.println("=====从尾到头的遍历=====");
        while (true){
            if (last == null) {
                break;
            }
            // 输出 last
            System.out.println(last);
            last = last.pre;
        }

        // 这个数据结构的主要价值 就是 添加 或 删除 元素 十分滴方便
        // 这里演示下 双向链表 添加数据是多么方便
        // 我需要在 关羽 和 张飞之间再添加一个 赵云

        // 1. 先创建 一个节点
        Node zhaoY = new Node("赵云");
        // 2. 将 此 节点 插入到双向链表里面
        zhaoY.next = zhangF;
        zhaoY.pre = guanY;
        // 画图
        zhangF.pre = zhaoY;
        guanY.next = zhaoY;

        // 因为上面的操作 first 指向了空 这里重新指向下
        first = liuB; // 让 first 引用指向 jack, 就是双向链表的头节点

        // 遍历
        System.out.println("=====从头到尾的遍历=====");
        while (true) { // 画桌面截图
            if (first == null) {
                break;
            }
            // 输出 first 信息
            System.out.println(first);
            first = first.next; // 指针向后移动一位 -- 画桌面截图
        }

    }
}

// 定义一个 Node 类，Node 对象 表示双向链表的一个结点
class Node{
    public Object item; // 真正存放数组的地方
    public Node next; // 指向后一个节点
    public Node pre; // 指向前一个节点

    public Node(Object name) {
        this.item = name;
    }

    @Override
    public String toString() {
        return "Node name=" + item;
    }
}